#include "../Logger/Logger.h"

using namespace std;


using namespace std;

void test_01() {
    int a[4] = {1, 2, 3, 4};
    LOG_INFO("a={}, &a={}  &a[0]={}", fmt::ptr(a), fmt::ptr(&a), fmt::ptr(&a[0]));
    LOG_INFO("sizeof(a):{}", sizeof(a));

    auto test = [](int *p) {
        LOG_INFO("sizeof(p):{} *p:{}", sizeof(p), *p);
    };

    test(a);
}

void test_02() {
    /**
     * int(*)[4] 是 C 语言中的一种指针类型，表示 “指向包含 4 个 int 元素的数组的指针”。
     * 括号 (*) 表明这是一个指针类型
     * 后面的 [4] 表明该指针指向的是一个包含 4 个元素的数组
     * 最前面的 int 表明数组中的元素类型是 int
     */
    int a[4] = {1, 2, 3, 4};
    // 数组a的地址是&a
    int(*p)[4] = &a;

    // 通过这种方式访问数组a的元素
    LOG_INFO("(*p)[0]:{}", (*p)[0]);
}

void test_03()
{
    int x = 4;
    int* p2 = &x;
    int** p1 = &p2;

    LOG_INFO("*(*p1):{}", *(*p1));
}

void test_04()
{
    int a[2][5] = {{1, 2, 3, 4, 5}, {6, 7, 8, 9, 0}};

    LOG_INFO("a={}, &a={}  &a[0]={}", fmt::ptr(a), fmt::ptr(&a), fmt::ptr(&a[0]));

    LOG_INFO("*a:{}", *a[0]);

    int (*p)[5] = a;
    LOG_INFO("(*p++)[0]:{}", (*p++)[0]);

    /**
     * error: lvalue required as increment operand
     * *a 的类型是 int[5]——一整行数组。
     * 数组整体不是一个可修改的左值，不能对其做自增运算。
     * 因此 (*a)++ 不合法，谈不上“得到什么”。
     */
    // (*a)++;

    /**
     * error: lvalue required as increment operand
     * 原因：a 是数组名，不是可修改的左值，不能对它做 ++ 运算。
     * 因此 a++ 本身非法，更谈不上 *(a++) 的返回值。
     */
    // *(a++);

    int n = (**a)++;
    LOG_INFO("n:{}", n);

    /**
     * 在 int a[2][5] 中，*a 的类型是 int [5]（即 “包含 5 个 int 元素的一维数组”）。
     * 具体解释：
     * a 作为二维数组名，在隐式转换为指针时类型是 int (*)[5]（指向包含 5 个 int 的数组的指针）。
     * 对其解引用（*a）后，得到的是该指针指向的目标 —— 二维数组中的第一个一维数组（即 a[0]），其类型为 int [5]。
     *
     * 进一步延伸：
     * 若对 *a 再做隐式转换，会得到指向该一维数组首元素的指针，类型为 int *。
     * 因此 **a 的类型是 int（即 a[0][0] 的类型）。
     */
    *(a+5); // 越界

    /**
     * 一个 指向 a[0][5] 的越界指针（类型为 int *，值等于 &a[0][5]）。
     * 推导步骤
     * a 退化为 int (*)[5]，指向第 0 行。
     * *a 得到第 0 行本身，随后立即再退化为 int *，指向该行的首元素 a[0][0]。
     * (*a) + 5 在这块地址上再偏移 5 个 int，于是指向 第 0 行末尾之后 的位置 a[0][5]。
     * 这已越过当前行的有效范围，形成 越界指针，但表达式本身仍是合法的 int * 值。
     */
    (*a)+5;
}

void test_05()
{
    int a[4] = {1, 2, 3, 4};
    LOG_INFO("*a:{}", *a);
    // LOG_INFO("*a:{}", *(a++));
    int *p = a;
    p++;
}

void logger_init()
{
    // 配置日志系统
    LoggerConfig config;
    config.baseFileName = "./log/unique_ptr_log";
    config.maxFileSize = 1024 * 1024; // 1MB
    config.maxFiles = 3;
    config.consoleOutput = true;
    config.level = spdlog::level::debug;

    // 初始化日志
    Logger::init(config);

    LOG_INFO("我是王乾");
}

int main()
{
    system("chcp 65001");

    logger_init();

    /**
     * 同样是sizeof(a)，结果不同，这是为什么？
     * 因为语境不同，所代表的意思不同
     * 在test函数中a是int*类型的指针
     * 在main函数中，a是数组
    */
    // test_01();

    // test_02();

    // test_03();

    test_04();

    // test_05();

    return 0;
}
